/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jreque.queue;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * An object describing an object's class and method
 * @author rzezioo
 */
class ObjectMethodDescriptor {
    /**
     * Class name to instantiate during execution.
     */
    private String object;

    /**
     * Method name to call.
     */
    private String method;

    public ObjectMethodDescriptor(String object, String method) {
        this.object = object;
        this.method = method;
    }

    /**
     * @return the object
     */
    public String getObject() {
        return object;
    }

    /**
     * @return the method
     */
    public String getMethod() {
        return method;
    }
    
    /**
     * Invokes task execution.
     * @param arguments List of arguments to be passed to execution invocation.
     */
    public void invoke(ArrayList arguments) {
        try {
            Class clazz = Class.forName(object);
            ArrayList<Class> argClasses = new ArrayList<Class>();
            if(arguments != null) {
                for(Object a : arguments) {
                    if(a != null) {
                        argClasses.add(a.getClass());
                    } else {
                        argClasses.add(null);
                    }
                }
            }
            Object obj = clazz.newInstance();
            
            for(Method m : clazz.getMethods()) {
                if(m.getName().equals(method)) {
                    Class[] pTypes = m.getParameterTypes();
                    if(pTypes.length != argClasses.size()) continue;
                    boolean match = true;
                    for(int i = 0; i < pTypes.length; i++) {
                        if(argClasses.get(i) == null) continue;
                        if(!pTypes[i].isAssignableFrom(argClasses.get(i))) {
                            match = false;
                            break;
                        }
                    }
                    if(match) {
                        Object[] argTab = new Object[0];
                        if(arguments != null) {
                            argTab = arguments.toArray();
                        }
                        m.invoke(obj, argTab);
                        return;
                    }
                }
            }
            throw new NoSuchMethodException("Nie znaleziono metody");
        } catch (ClassNotFoundException e) {
            System.err.println(e.getMessage());
        } catch (InstantiationException e) {
            System.err.println(e.getMessage());
        } catch (IllegalAccessException e) {
            System.err.println(e.getMessage());
        } catch (InvocationTargetException e) {
            System.err.println(e.getMessage());
        } catch (NoSuchMethodException e) {
            System.err.println(e.getMessage());
        }
    }
}
